
/*********************
 ***	Base64.c   ***
 *********************/
#include	"Uigp/igp.h"
#include	"Base64.h"


static const unsigned char alphabet_[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const unsigned char pad_ = '=';

static const int max_columns_ = 72;




int
base64_decode( u_char *input, int inBytes, u_char **data, int *bytes )
{
int	i;
int	decoder_[256];
int	member_[256];

	for( i = 0 ; i < 256 ; i++ )
		member_[i] = 0;
	
	for( i = 0 ; i < sizeof (alphabet_) ; i++ ){
		decoder_[alphabet_[i]] = i;
		member_[alphabet_[i]] = 1;
	}



	*bytes = ((inBytes + 3) / 4) * 3 + 1 ;
	*data = (u_char *)malloc( *bytes );

	int char_count = 0;
	int bits = 0;

	u_char	*tp = *data;
	u_char	*sp = input;
	
	for( i = 0 ; i < inBytes; i++, sp++ ){

		if( *sp == pad_)	break;

		if( member_[ *sp ] == 0 )
			continue;

		bits += decoder_[ *sp ];
		char_count++;

		if( char_count < 4 ){
			bits <<= 6;
			continue;
		}


		*tp++ = bits >> 16;
        *tp++ = (bits >> 8) & 0xff;
        *tp++ = bits & 0xff;
		bits = 0;
		char_count = 0;
	}

	if( *sp == pad_ ){
		if( char_count == 2 ){
			*tp++ = bits >> 10;
			char_count = 0;
		}
		if( char_count == 3 ){
			*tp++ = bits >> 16;
			*tp++ = (bits >> 8) & 0xff;
			char_count = 0;
        }
	}

	*tp = 0;
	*bytes = tp - (*data );


	if( char_count > 0 )	return( 2 );

	return( 1 );
}














/*
#include "ace/OS.h"
#include "VIM_Base64.h"
#include "ace/Log_Msg.h"

const unsigned char VIM_Base64::alphabet_[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

const unsigned char VIM_Base64::pad_ = '=';

int VIM_Base64::max_columns_ = 72;
int VIM_Base64::init_ =0;
unsigned char VIM_Base64::decoder_[256];

unsigned char VIM_Base64::member_[256];


VIM_Base64::VIM_Base64()
{
	if (init_ == 0)
    {
		for (unsigned char i = 0; i < sizeof (alphabet_); ++i)
        {
			VIM_Base64::decoder_[alphabet_[i]] = i;
			VIM_Base64::member_[alphabet_[i]] = 1;
        }
		init_ = 1;
    }
}

VIM_Base64::~VIM_Base64()
{
}	



unsigned char*
VIM_Base64::encode (const unsigned char* input,
                    const size_t input_len,
                    size_t* output_len)
{
  
  if (!input)
    return 0;

  unsigned char* result = 0;

  size_t length = ((input_len + 2) / 3) * 4;
  size_t num_lines = length / max_columns_ + 1;
  length += num_lines + 1;
  result = (unsigned char *) malloc(length);
 

  int char_count = 0;
  int bits = 0;
  size_t pos = 0;
  int cols = 0;

  for (size_t i = 0; i < input_len; ++i)
    {
      if (input[i] > 255) {
        delete[] result;
        return 0;
      }

      bits += input[i];
      char_count++;

      if (char_count == 3)
        {
          result[pos++] = alphabet_[bits >> 18];
          result[pos++] = alphabet_[(bits >> 12) & 0x3f];
          result[pos++] = alphabet_[(bits >> 6) & 0x3f];
          result[pos++] = alphabet_[bits & 0x3f];
          cols += 4;
          if (cols == max_columns_) {
            result[pos++] = '\n';
            cols = 0;
          }
          bits = 0;
          char_count = 0;
        }
      else
        {
          bits <<= 8;
        }
    }


  if (char_count != 0)
    {
      bits <<= (16 - (8 * char_count));
      result[pos++] = alphabet_[bits >> 18];
      result[pos++] = alphabet_[(bits >> 12) & 0x3f];
      if (char_count == 1)
        {
          result[pos++] = pad_;
          result[pos++] = pad_;
        }
      else
        {
          result[pos++] = alphabet_[(bits >> 6) & 0x3f];
          result[pos++] = pad_;
        }
      if (cols > 0)
        result[pos++] = '\n';
    }

  result[pos] = 0;
  *output_len = pos;
  return result;
}



size_t
VIM_Base64::length (const unsigned char* input)
{
  
  unsigned char* ptr = (unsigned char*)input;
  while (*ptr != 0 &&
         (member_[*(ptr)] == 1 || *ptr == pad_
          || ACE_OS_String::ace_isspace (*ptr)))
    ptr++;

  size_t len = ptr - input;
  len = ((len + 3) / 4) * 3 + 1 ;
  return len;
}


unsigned char*
VIM_Base64::decode (const unsigned char* input, size_t* output_len)
{
  
  if (!input)
    return 0;

  size_t result_len = length (input);
  unsigned char* result = 0;
  result = (unsigned char *) malloc(result_len);
  //ACE_NEW_RETURN (result, unsigned char[result_len], 0);

  unsigned char* ptr = ACE_const_cast (unsigned char*, input);
  while (*ptr != 0 &&
         (member_[*(ptr)] == 1 || *ptr == pad_
          || ACE_OS_String::ace_isspace (*ptr)))
    ptr++;
  size_t input_len = ptr - input;

  int char_count = 0;
  int bits = 0;
  size_t pos = 0;

  size_t i = 0;
  for (; i < input_len; ++i)
    {
      if (input[i] == pad_)
        break;
      if (input[i] > 255 || !member_[input[i]])
        continue;
      bits += decoder_[input[i]];
      char_count++;

      if (char_count == 4)
        {
          result[pos++] = bits >> 16;
          result[pos++] = (bits >> 8) & 0xff;
          result[pos++] = bits & 0xff;
          bits = 0;
          char_count = 0;
        }
      else
        {
          bits <<= 6;
        }
    }

  int errors = 0;
  if ( i == input_len)
    {
      if (char_count)
        {
          ACE_DEBUG ((LM_ERROR,
                      ACE_TEXT ("Decoding incomplete: atleast %d bits truncated\n"),
                      (4 - char_count) * 6));
          errors++;
        }
    }
  else
    {
      switch (char_count)
        {
        case 1:
          ACE_DEBUG ((LM_ERROR,
                      ACE_TEXT ("Decoding incomplete: atleast 2 bits missing\n")));
          errors++;
          break;
        case 2:
          result[pos++] = bits >> 10;
          break;
        case 3:
          result[pos++] = bits >> 16;
          result[pos++] = (bits >> 8) & 0xff;
          break;
        }
    }

  if (errors)
    {
      delete[] result;
      return 0;
    }
  result[pos] = 0;
  *output_len = pos;


  return result;
}

*/


